package ru.it.xml;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 *
 * @author Dmitry
 */
public class SaxHandler extends DefaultHandler {

    public  Map<String, SAXQuery> queries;
    private List<String> curpath;
    private String[] empty;
    org.w3c.dom.Element rootnode = null;

    private boolean isEquals(String[] path) {
        if(path.length != curpath.size())
            return false;
        for(int i=0; i<path.length; i++) {
            if(!(path[i].equals(curpath.get(i)) || path[i].equals("*"))) {
                return false;
            }
        }
        
        return true;
    }

    public SaxHandler() {
        empty = new String[]{"1"};
        queries = new HashMap<String, SAXQuery>();
        curpath = new ArrayList<String>();
    }

    public void close() {
        empty = null;
        queries = null;
        
        curpath.clear();
        curpath = null;
    }

    public void startDocument() throws SAXException {
     //   System.out.println("----------------------- Start of the document ----------------------------");
    }

    public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
        //  System.out.println("Element q-name: [" + qName + "] started."+String.valueOf(i));
        if(null == rootnode) {
            try {
                DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                Document doc = builder.newDocument();
                rootnode = doc.createElement(qName);

                for(int i=0; i<attrs.getLength(); i++)
                    rootnode.setAttribute(attrs.getQName(i), attrs.getValue(i));
            }
            catch(Throwable th) {
                throw new SAXException(th.getMessage());
            }
        }

        final String[] parts = qName.split(":");
        curpath.add(parts[parts.length-1]);

        for (String key : queries.keySet()) {
            if (queries.get(key).found) {
                queries.get(key).textNode = false;
                queries.get(key).result += "<" + qName + ">";
            }
        }
        for (String key : queries.keySet()) {
            if (isEquals(queries.get(key).getPath())) {
                queries.get(key).found = true;
                queries.get(key).exist = true;
                queries.get(key).result = "";
                queries.get(key).depth = curpath.size();
            }
        }
    }

    public void characters(char[] chars, int start, int length) throws SAXException {
        String value = new String(chars);
        for (String key : queries.keySet()) {
            if (queries.get(key).found) {
                queries.get(key).result += new String(value.substring(start, start + length));
            }
        }
    }

    public void endDocument() throws SAXException {
        // System.out.println("----------------------- End of the document ----------------------------");
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
        //  if(StartWrite)
        //      queries.get(queryIndex).setResult(result);
        final String[] parts = qName.split(":");
        curpath.remove(parts[parts.length-1]);
        
        for (String key : queries.keySet()) {
            if (queries.get(key).found && curpath.size() < queries.get(key).depth) {
                queries.get(key).found = false;
            }
        }
        for (String key : queries.keySet()) {
            if (queries.get(key).found) {
                queries.get(key).setResult(queries.get(key).getResult() + "</" + qName + ">");
            }
        }
    }
}
